package com.wdb007.venus.svc.biz.manager;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.wdb007.venus.svc.facade.constant.BizConstants;

@Component("smsSendManager")
public class SmsSendManager implements InitializingBean{

	private Logger logger = LoggerFactory.getLogger(SmsSendManager.class);
	
	private String product ;
	private String domain ;
	private String accessKeyId ;
	private String accessKeySecret ;
	private String region ;
	private String signName ;
	private String templateCode ;
	
	@Autowired
	private ConfigInfoManager configInfoManager;
	
	public boolean sendMessage(String phone, String verifyCode) {
		logger.info("向 {} 发送验证码 {} 开始", phone, verifyCode);
		System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
		System.setProperty("sun.net.client.defaultReadTimeout", "10000");
		IAcsClient client = new DefaultAcsClient();
		
		IClientProfile profile = DefaultProfile.getProfile(region, accessKeyId, accessKeySecret);
		try {
			DefaultProfile.addEndpoint(region, region, product, domain);
		} catch (ClientException e1) {
			e1.printStackTrace();
		}
		client = new DefaultAcsClient(profile);
		
		boolean sendSuccess = false ;
		//组装请求对象
		SendSmsRequest request = new SendSmsRequest();
		//使用post提交
		request.setMethod(MethodType.POST);
		
		//必填:待发送手机号。支持以逗号分隔的形式进行批量调用，批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
		request.setPhoneNumbers(phone);
		//必填:短信签名-可在短信控制台中找到
		request.setSignName(signName);
		//必填:短信模板-可在短信控制台中找到
		request.setTemplateCode(templateCode);
		
		//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
		//友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
		request.setTemplateParam("{\"code\":\""+ verifyCode +"\"}");
		
		//请求失败这里会抛ClientException异常
		try {
			SendSmsResponse sendSmsResponse = client.getAcsResponse(request);
			if(sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
				logger.info("向 {} 发送验证码 {} 结束", phone, verifyCode);
				sendSuccess = true ;
			}else {
				logger.warn("向[{}]发送验证码失败，响应码为{}， 响应信息为{}", phone, sendSmsResponse.getCode(), sendSmsResponse.getMessage());
			}
		} catch (ClientException e) {
			logger.error("向[" + phone + "]发送验证码异常", e);
			sendSuccess = false ;
		}
		return sendSuccess;
	}

	/**
	 * 余额充值到账
	 * @param phone
	 * @param money
	 * @param type 0 系统赠送 1 实际充值
	 * @return
	 */
	public boolean sendRechangeToAccountMsg(String phone, String money, int type) {
		Map<String, Object> params = new HashMap<>();
		params.put("money", money);
		if(type == 0) {//系统赠送
			return sendAliMsg(params, BizConstants.RECHARGE_TO_ACCOUNT_MSG, phone);
		}else {//实际充值
			return sendAliMsg(params, BizConstants.PAID_SUCCESS_TO_ACCOUNT_MSG, phone);
		}
	}
	/**
	 * 会员卡到账
	 * @param phone
	 * @param viptype 会员类型
	 * @param endtime 到期时间
	 * @param payType 支付类型
	 * @return
	 */
	public boolean sendPaidVipToAccountMsg(String phone, String viptype, String endtime, int payType) {
		Map<String, Object> params = new HashMap<>();
		params.put("viptype", viptype);
		params.put("endtime", endtime);
		if(BizConstants.VIP_CHARGE_TYPE_20.equals(payType)) {
			return sendAliMsg(params, BizConstants.SYS_GIVE_VIP_TO_ACCOUNT_MSG, phone);
		}else {
			return sendAliMsg(params, BizConstants.PAID_VIP_TO_ACCOUNT_MSG, phone);
		}
		
	}
	
	/**
	 * 借阅费用超过书籍定价70%
	 * @param phone
	 * @param bookName 书籍名称
	 * @param price 70%的价格
	 * @return
	 */
	public boolean sendBoorowFeeOverPriceMsg(String phone, String bookName, String price) {
		Map<String, Object> params = new HashMap<>();
		params.put("bookName", bookName);
		params.put("price", price);
		return sendAliMsg(params, BizConstants.BORROW_FEE_OVER_PRICE_MSG, phone);
	}
	
	/**
	 * 押金缴纳成功通知
	 * @param phone
	 * @return
	 */
	public boolean sendPayDepositMsg(String phone) {
		Map<String, Object> params = new HashMap<>();
		params.put("money", 99);
		return sendAliMsg(params, BizConstants.PAY_DEPOSIT_MSG, phone);
	}
	
	/**
	 * 图书借阅超额通知
	 * @param phone
	 * @param borrowNum 借阅本数
	 * @param outNum 超额本数
	 * @return
	 */
	public boolean sendBoorowBookOverMsg(String phone, String borrowNum, String outNum) {
		Map<String, Object> params = new HashMap<>();
		params.put("borrowNum", borrowNum);
		params.put("outNum", outNum);
		params.put("price", 2);
		return sendAliMsg(params, BizConstants.BORROW_BOOK_OVER_MSG, phone);
	}
	
	/**
	 * 会员卡到期提醒
	 * @param phone
	 * @param viptype 会员卡类型
	 * @return
	 */
	public boolean sendVipExpireTimeMsg(String phone, int viptype) {
		Map<String, Object> params = new HashMap<>();
		if(BizConstants.VIP_TYPE_1.equals(viptype)) {
			params.put("viptype", "月卡");
		}else if(BizConstants.VIP_TYPE_2.equals(viptype)) {
			params.put("viptype", "年卡");
		}
		params.put("days", 6);
		return sendAliMsg(params, BizConstants.VIP_EXPIRE_TIME_MSG, phone);
	}
	
	public boolean sendBackDepositSuccessMsg(String phone) {
		return sendAliMsg(null, BizConstants.BACK_DEPOSIT_SUCCESS_MSG, phone);
	}
	
	//通用模板，验证码 sendMessage 代码不变
	public boolean sendAliMsg(Map<String, Object> params, String templateCode, String phone) {
		String paramsValue = "";
		String content = "";
		if(params != null) {
			for(String key : params.keySet()){
				   content += "\""+ key + "\":\""+ params.get(key) +"\", ";
			}
			paramsValue = "{"+content.substring(0, content.length()-2) + "}";
		}
		
		logger.info("sendAliMsg:templateCode:{},send content[{}]", templateCode, paramsValue);
		
		System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
		System.setProperty("sun.net.client.defaultReadTimeout", "10000");
		IAcsClient client = new DefaultAcsClient();
		
		IClientProfile profile = DefaultProfile.getProfile(region, accessKeyId, accessKeySecret);
		try {
			DefaultProfile.addEndpoint(region, region, product, domain);
		} catch (ClientException e1) {
			e1.printStackTrace();
		}
		client = new DefaultAcsClient(profile);
		
		boolean sendSuccess = false ;
		//组装请求对象
		SendSmsRequest request = new SendSmsRequest();
		//使用post提交
		request.setMethod(MethodType.POST);
		
		//必填:待发送手机号。支持以逗号分隔的形式进行批量调用，批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
		request.setPhoneNumbers(phone);
		//必填:短信签名-可在短信控制台中找到
		request.setSignName(signName);
		//必填:短信模板-可在短信控制台中找到
		request.setTemplateCode(templateCode);
		
		//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
		//友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,否则会导致JSON在服务端解析失败
		if(paramsValue.length() > 0) {
			request.setTemplateParam(paramsValue);
		}
		
		//请求失败这里会抛ClientException异常
		try {
			SendSmsResponse sendSmsResponse = client.getAcsResponse(request);
			if(sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
				logger.info("sendRechangeToAccountMsg,向 {} 发送短信{}通知 结束", phone, templateCode);
				sendSuccess = true ;
			}else {
				logger.warn("向 {} 发送短信{}通知失败，响应码为{}， 响应信息为{}", phone, templateCode, sendSmsResponse.getCode(), sendSmsResponse.getMessage());
			}
		} catch (ClientException e) {
			logger.error("向[" + phone + "]发送短信"+templateCode+"通知异常", e);
			sendSuccess = false ;
		}
		return sendSuccess;
	}
	
	public void sendErrorMsg(String phone) {
		sendAliMsg(null, "SMS_126364083", phone);
	}
	
	public static void main(String[] args) {
//		SmsSendManager sendManager = new SmsSendManager();
//		sendManager.sendMessage("18516517603", "111111");
		
		System.out.println("aa,".substring(0, "aa,".length()-1));
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		product = configInfoManager.getValue("sms.product");
		domain = configInfoManager.getValue("sms.domain");
		accessKeyId = configInfoManager.getValue("sms.accessKeyId");
		accessKeySecret = configInfoManager.getValue("sms.accessKeySecret");
		region = configInfoManager.getValue("sms.region");
		signName = configInfoManager.getValue("sms.signName");
		templateCode = configInfoManager.getValue("sms.templateCode");
		
	}
}
